<script setup lang="ts">
import { getCurrentInstance, nextTick, onMounted, reactive, ref, } from 'vue';
import dialogTool from '../common/dialogTool';
import helpler from '../common/helpler';
import { DialogResult } from '../common/enums';

const dialog = ref();
const props = defineProps<{ width: string, height: string, icon?: string, isShowMask?: boolean }>();
const data = reactive({
    title: "",
    isVisible: false,
});
const instance = getCurrentInstance();
const emits = defineEmits(["beforeClosing"]);
let startPoint: any;
// const self = getCurrentInstance();
let id = "";
const init = () => {
    if (props.isShowMask) {
        dialogTool.showMask()
    }
    dialogTool.setCurrentDialog(instance);
    let width = parseToFloat(props.width);
    let height = parseToFloat(props.height);
    dialog.value.style.zIndex = dialogTool.increaseZIndex(1).toString();
    dialog.value.style.height = (height - 4) + "px";
    dialog.value.style.width = (width - 4) + "px";
    dialog.value.style.top = (document.documentElement.clientHeight - height) / 2.6 + "px";
    dialog.value.style.left = (document.documentElement.clientWidth - width) / 2 + "px";
}

const startDrag = (evt: MouseEvent) => {
    let mask = dialogTool.createDragMask();
    mask.style.zIndex = dialogTool.increaseZIndex(1).toString();
    document.body.appendChild(mask);
    startPoint = {
        x: evt.clientX,
        y: evt.clientY,
        top: dialog.value.offsetTop,
        left: dialog.value.offsetLeft,
    };
    document.body.addEventListener("selectstart", helpler.onSelectStart);
    mask.addEventListener("mousemove", onMouseMove);
    mask.addEventListener("mouseup", endDrag);
}

const onMouseMove = (evt: MouseEvent) => {
    startPoint.left = startPoint.left - startPoint.x + evt.clientX;
    if (startPoint.left < 0) {
        startPoint.left = 0;
    }
    else if (startPoint.left + 35 > document.documentElement.clientWidth) {
        startPoint.left = document.documentElement.clientWidth - 35;
    }
    startPoint.top = startPoint.top - startPoint.y + evt.clientY;
    if (startPoint.top < 0) {
        startPoint.top = 0;
    } else if (startPoint.top + 35 > document.documentElement.clientHeight) {
        startPoint.top = document.documentElement.clientHeight - 35;
    }
    dialog.value.style.top = startPoint.top + "px";
    dialog.value.style.left = startPoint.left + "px";
    startPoint.x = evt.clientX;
    startPoint.y = evt.clientY;
}

const endDrag = (evt: Event): void => {
    let mask = evt.target as any;
    document.body.removeEventListener("selectstart", helpler.onSelectStart);
    mask.removeEventListener("mouseup", endDrag);
    mask.removeEventListener("mousemove", onMouseMove);
    mask.parentNode.removeChild(mask);
    dialogTool.minusZIndex(1);
}

const parseToFloat = (value: string): number => {
    if (helpler.isPercent(value)) {
        return (helpler.parseFloat(value.replace("%", "")) / 100) * document.documentElement.clientWidth;
    } else if (value.indexOf("px") > -1) {
        return parseFloat(value.replace("px", ""));
    }
    else {
        return parseFloat(value);
    }
}

let currentResolve: ((value: DialogResult | PromiseLike<DialogResult>) => any) | null;
// let currentReject: (reason?: any) => void;

const open = (title: string): Promise<DialogResult> => {
    return new Promise((resolve, reject) => {
        if (data.isVisible) {
            reject();
            return;
        }
        currentResolve = resolve;
        // currentReject = reject;
        data.title = title;
        data.isVisible = true;
        dialog.value.focus();
        nextTick(() => {
            init();
        });
        // resolve(id);
    });
}

const closeDialog = () => {
    data.isVisible = false;
    if (props.isShowMask) {
        dialogTool.hideMask();
    }
    dialogTool.removeDialog(instance);
}

const onCloseMouseDown = (evt: MouseEvent) => {
    evt.stopPropagation();
}

const close = (dialogResult: DialogResult, isDestroy: boolean): boolean => {
    let a = { id: id, dialogResult: dialogResult, isPrevent: false };
    emits("beforeClosing", a);
    if (a.isPrevent === true) {
        return false;
    }
    if (dialogResult == undefined) {
        dialogResult = DialogResult.Unknow;
    }
    currentResolve && currentResolve(dialogResult);
    closeDialog();
    if (isDestroy) {

    }
    currentResolve = null;
    return true;
}
const closeInternal = () => {
    currentResolve && currentResolve(DialogResult.CloseWindow);
    closeDialog();
    currentResolve = null;
    return true;
}

onMounted(() => {
    id = helpler.genRandomString();
    nextTick(() => {
        dialog.value.setAttribute("id", id);
    });
})


const dialogKeyDown = (evt: KeyboardEvent) => {
    evt.stopPropagation();
}

defineExpose({ open, close });
</script>
<template>
    <div ref="dialog" class="app-dialog" v-show="data.isVisible" style="display: none;"
        @keydown="dialogKeyDown($event)">
        <div class="app-dialog-head" @mousedown="startDrag">
            <span>{{ data.title }}</span>
            <div class="app-dialog-close" @click="closeInternal" @mousedown="onCloseMouseDown">
                <el-icon>
                    <Close />
                </el-icon>
            </div>
        </div>
        <div class="app-dialog-body">
            <slot v-if="data.isVisible"></slot>
        </div>
    </div>
</template>